/*
 * Guild.h
 *
 *  Created on: 2014. 7. 17.
 *      Author: mega
 */

#ifndef GUILDSERVER_GUILD_H_
#define GUILDSERVER_GUILD_H_

#include <map>
#include <string>
#include <memory>

#include <Dispatcher/Static.h>

#include "Member.h"
#include "../idl/Guild.h"

namespace GuildServer {

class Guild
{
public:
	struct GuildInfo
	{
		uint32_t	_masterSeq;		// 길드 마스터 SEQ
		uint16_t	_grade;			// 길드 등급
		uint16_t	_status;		// 길드 상태
		uint16_t	_exposure;		// 길드 노출 (0:노출, 1:비노출)

		uint16_t	_buffLevel;		// 길드 버프 레벨
		uint16_t	_buffType;		// 길드 버프 타입
		uint16_t	_buffValue;		// 길드 버프 수치

		int32_t	_score;			// 길드 점수
		uint32_t	_prevScore;		// 이전 길드 점수

		uint32_t	_rank;
		uint32_t	_prevRank;

		time_t		_regDate;		// 길드 생성 시간

		std::string	_password;		// 길드 비밀번호
		std::string	_intro;			// 길드 소개글
		std::string	_name;			// 길드 명

		void Clear()
		{
			_masterSeq	= 0;
			_grade		= 0;
			_status		= 0;
			_exposure	= 0;
			_buffLevel	= 0;
			_buffType	= 0;
			_score		= 0;
			_prevScore = 0;
			_rank		= 0;
			_prevRank	= 0;
			_regDate	= 0;
			_intro.clear();
			_name.clear();
			_password.clear();
		}

		GuildInfo()
		{
			Clear();
		}
	};

public:
	typedef std::map<uint32_t, std::shared_ptr<Member>>	MEMBERTREE;

public:
	Guild();
	virtual ~Guild();

	void		Initialize(uint32_t channelKey, uint32_t guildSeq);
	void		Finalize();

	int			LoadData( uint32_t guild_seq );
	void		Open(GuildInfo & info);

	bool		AddMember(std::shared_ptr<Member> pMember);
	bool		DelMember(uint32_t userSeq);
	std::shared_ptr<Member>	GetMember(uint32_t userSeq);
	std::shared_ptr<Member>	GetMaster();

	bool		IsExistMember(uint32_t userSeq);
	bool		IsGuildMaster(uint32_t userSeq);

	int			GetMemberCount() { return m_MemberTree.size(); }
	int			GetMemberCountExceptMaster();
	int			GetConnectMemberCount();
	int			GetMaxMemberCount();

	int			GetRank();

	uint32_t	GetSeq() { return m_GuildSeq; }
	GuildInfo &	GetData() { return m_GuildInfo; }
	MEMBERTREE &	GetMemberTree() { return m_MemberTree; }

	int16_t		JoinMember(JoinGuildSyn & syn, uint32_t& a_tmCooldown );
	int16_t		LeaveMember(uint32_t member_seq);
	int16_t		LeaveMaster();
	int16_t		KickoutMember(uint32_t member_seq);
	void		UpdateGradeDown();
	void		UpdateBuffDown();

	void		ChangeScore(int score);

	void		FlushGuildPoint();

	void		SetFlushDB(bool bFlushDB) { m_bFlushDB = bFlushDB; }
	bool		GetFlushDB() { return m_bFlushDB; }

	void		OnTime();
	void		SetTimer();

private:
	uint32_t	m_GuildSeq;
	uint32_t	m_ChannelKey;
	bool		m_bFlushDB;
	bool		m_bWorkTimer;

	::Dispatcher::Timer * m_pTimer;

	GuildInfo	m_GuildInfo;

	MEMBERTREE	m_MemberTree;

	uint64_t m_tmRankUpdated;
};

} /*GuildServer*/


#endif /* GUILDSERVER_GUILD_H_ */
